package com.zzyl.service.impl;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.zzyl.constant.Constants;
import com.zzyl.dto.WxLoginDto;
import com.zzyl.entity.Member;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.MemberMapper;
import com.zzyl.properties.JwtTokenManagerProperties;
import com.zzyl.service.CustomerService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.vo.LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;

@Service
public class CustomerServiceImpl implements CustomerService {
    @Value("${zzyl.framework.wx.appid}")
    private String appid;
    @Value("${zzyl.framework.wx.secret}")
    private String secret;

    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private JwtTokenManagerProperties jwtTokenManagerProperties;

    /**
     * 微信小程序登录校验
     * @param wxLoginDto
     * @return
     */
    @Override
    public LoginVo login(WxLoginDto wxLoginDto) {
        //1.通过登录凭证完成登录 获取到唯一的openid
        String openId = getOpenId(wxLoginDto.getCode());
        //2.通过openid查询数据库的表
        Member member = memberMapper.selectByOpenId(openId);
        //3.通过手机兑换码获取手机号
        String phone = getPhone(wxLoginDto.getPhoneCode());
        //4.判断用户是否为新用户
        if(null == member){
            member = new Member();
            member.setPhone(phone);
            member.setCreateTime(LocalDateTime.now());
            member.setUpdateTime(LocalDateTime.now());
            member.setCreateBy(1L);
            member.setOpenId(openId);
            String name = Constants.DEFAULT_NICKNAME_PREFIX.get((int)(Constants.DEFAULT_NICKNAME_PREFIX.size() * Math.random())) + phone.substring(7);
            member.setName(name);
            memberMapper.save(member);
        }else {
            //用户已注册
            if(!phone.equals(member.getPhone())){
                member.setPhone(phone);
                member.setUpdateTime(LocalDateTime.now());
                memberMapper.update(member);
            }
        }
        //5.生成token
        HashMap<String, Object> clamis = new HashMap<>();
        clamis.put("id",member.getId());
        clamis.put("name",member.getName());

        String token = JwtUtil.createJWT(jwtTokenManagerProperties.getBase64EncodedSecretKey(),
                jwtTokenManagerProperties.getTtl(), clamis);

        //6.构建返回结果
        LoginVo vo = new LoginVo();
        vo.setToken(token);
        vo.setNickName(member.getName());
        return vo;
    }
    /**
     * 微信登录获取openid
     */
    private String getOpenId(String code){
        HashMap<String, Object> paramData = new HashMap<>();
        paramData.put("appid",appid);
        paramData.put("secret",secret);
        paramData.put("js_code",code);
        paramData.put("grant_type","authorization_code");

        HttpResponse response= HttpUtil.createGet(Constants.OPENID_REQUEST_URL).form(paramData).execute();
        String json = response.body();
        JSONObject jsonObject = JSONUtil.parseObj(json);
        Integer errcode = jsonObject.getInt("errcode");
        if(errcode != null && errcode != 0){
            //失败了
            throw new BaseException(BasicEnum.GET_OPENID_ERROR);
        }
        return jsonObject.getStr("openid");
    }
    /**
     * 获取用户token
     */
    private String getAccessToken(){
        HashMap<String, Object> paramData = new HashMap<>();
        paramData.put("grant_type","client_credential");
        paramData.put("appid",appid);
        paramData.put("secret",secret);
        HttpResponse response = HttpUtil.createGet(Constants.WX_ACCESS_TOKEN_URL).form(paramData).execute();
        String jsonResopnse = response.body();
        JSONObject jsonObject = JSONUtil.parseObj(jsonResopnse);
        if(jsonObject.getStr("access_token") == null){
            throw new BaseException(BasicEnum.GET_TOKEN_ERROR);
        }
        return jsonObject.getStr("access_token");
    }
    /**
     * 获取用户手机号码
     */
    private String getPhone(String phoneCode){
        //1.获取AccessToken
        String accessToken = getAccessToken();
        //2.通过AccessToken和code获取手机号
        HashMap<Object, Object> paramData = new HashMap<>();
        paramData.put("code",phoneCode);

        HttpResponse response = HttpUtil.createPost(Constants.WX_GET_PHONE_URL + accessToken).body(JSONUtil.toJsonStr(paramData)).execute();
        String jsonRespone = response.body();
        JSONObject jsonObject = JSONUtil.parseObj(jsonRespone);
        if(jsonObject.getInt("errcode") != null && jsonObject.getInt("errcode") != 0){
            throw new BaseException(BasicEnum.GET_PHONE_ERROR);
        }
        JSONObject phoneInfo = jsonObject.getJSONObject("phone_info");
        return phoneInfo.getStr("phoneNumber");
    }
}
